package com.jinxin.platform.cdzxkacs.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jinxin.platform.base.common.pojo.JsonResult;
import com.jinxin.platform.cdzxkacs.bean.*;
import com.jinxin.platform.cdzxkacs.common.SysUserVO;
import com.jinxin.platform.cdzxkacs.mapper.*;
import com.jinxin.platform.cdzxkacs.redis.RedisUtil;
import com.jinxin.platform.cdzxkacs.rpc.SysUserRpc;
import com.jinxin.platform.cdzxkacs.service.IAcsTimeTemplateService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.*;

/**
 * All rights Reserved, Designed By www.beonelot.com
 *
 * @version: V1.0
 * @Copyright: www.beonelot.com Inc. All rights reserved.
 * @Description：
 * @Date: 2021-01-29
 * @Author: Lingnan
 **/
@Service
public class AcsTimeTemplateServiceImpl implements IAcsTimeTemplateService {

    @Autowired
    private CdzxkacsTimeTempalteMapper timeTempalteMapper;
    @Autowired
    private SysUserRpc sysUserRpc;
    @Autowired
    private CdzxkacsWeekPlanMapper weekPlanMapper;
    @Autowired
    private CdzxkacsDayPlanMapper dayPlanMapper;
    @Autowired
    private CdzxkacsTimeSectionMapper timeSectionMapper;
    @Autowired
    private CdzxkacsExceptionMapper exceptionMapper;
    @Autowired
    private CdzxkacsUserTemplateMapper userTemplateMapper;
    @Autowired
    private CdzxkacsDeviceMapper deviceMapper;

    @Override
    public List<CdzxkacsTimeTempalte> list(HashMap param) {
        return timeTempalteMapper.list(param);
    }

    @Override
    public List<CdzxkacsTimeTempalte> listPage(HashMap param) {
        return timeTempalteMapper.listPage(param);
    }

    @Override
    public int listPageCount(HashMap param) {
        return timeTempalteMapper.listPageCount(param);
    }

    @Override
    public JsonResult delete(String id, String deviceId) {
        if(StringUtils.isEmpty(id) || StringUtils.isEmpty(deviceId)){
            return JsonResult.error("时间模板不存在");
        }
        // 先删除宇视的
        CdzxkacsDevice device = deviceMapper.selectByKey(deviceId);
        if(device == null){
            return JsonResult.error("设备不存在");
        }
        JsonResult jsonResult = sysUserRpc.deleteTimeTemplates(id, device.getSerialNum(), device.getProductCode());
        if(jsonResult != null && jsonResult.getSuccess()){
            HashMap param = new HashMap();
            param.put("timeTemplateId",id);
            List<CdzxkacsUserTemplate> list = userTemplateMapper.list(param);
            if(list != null && list.size() > 0){
                return JsonResult.error("时间模板在使用中，无法删除");
            }
            int result = timeTempalteMapper.deleteByKey(id);
            if(result > 0){
                deleteAll(id);
                return JsonResult.ok("删除成功","");
            }
        }
        return JsonResult.error("删除失败");
    }

    private void deleteAll(String id){
        HashMap param1 = new HashMap();
        param1.put("templateId",id);
        List<CdzxkacsWeekPlan> weekPlanList = weekPlanMapper.list(param1);
        for (CdzxkacsWeekPlan wPan : weekPlanList) {
            HashMap param2 = new HashMap();
            param2.put("weekPlanId",wPan.getId());
            List<CdzxkacsDayPlan> dayPlans = dayPlanMapper.list(param2);
            for(CdzxkacsDayPlan dayPlan : dayPlans){
                timeSectionMapper.deleteByDayId(dayPlan.getId());
            }
            dayPlanMapper.deleteByWeekId(wPan.getId());
        }
        weekPlanMapper.deleteByTemplateId(id);
    }

    private String parseTimeSlot(int num){
        if(num < 10){
            return "0"+num;
        }else if(num >= 24){
            return "00";
        }else {
            return num+"";
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public JsonResult saveOrUpdate(CdzxkacsTimeTempalte record) {
        if (record == null){
            return JsonResult.error("参数错误，操作失败");
        }
        SysUserVO currentUser = sysUserRpc.getCurrentUser();
        if (currentUser == null){
            return JsonResult.error("获取当前用户失败");
        }
        String id = record.getId();
        CdzxkacsDevice device = deviceMapper.selectByKey(record.getDeviceId());
        if(device != null){
            int count;
            String msg;
            String bfTimeStr = record.getBfTimeStr();
            String exceptionDateStr = record.getExceptionDate();
            JSONObject jsonObject = JSON.parseObject(bfTimeStr);
            JSONArray exTimeArr = JSONArray.parseArray(exceptionDateStr);
            CdzxkacsTimeTempalte timeTempalte = new CdzxkacsTimeTempalte();
            String newId = !StringUtils.isEmpty(id) ? id : System.currentTimeMillis() + "";
            BeanUtils.copyProperties(record,timeTempalte);
            timeTempalte.setId(newId);
            if(StringUtils.isEmpty(id)){
                JsonResult jsonResult = sysUserRpc.createOrUpdateTimeTemplates(device.getSerialNum(),
                        device.getProductCode(), timeTempalte, jsonObject, exTimeArr,false);
                if(jsonResult != null && jsonResult.getSuccess()){
                    record.setId(newId);
                    record.setUpdateTime(LocalDateTime.now());
                    record.setUpdateUserId(currentUser.getUserId());
                    record.setUpdateUser(currentUser.getUserAccount());
                    count = timeTempalteMapper.insert(record);
                    // 格式 {"1":[6,8,7],"3":[7],"4":[10],"6":[11]}
                    saveOrUpdateTimeSection(record, jsonObject,exTimeArr,false);
                    msg = "新增成功";
                }else {
                    String errMsg = jsonResult != null ? jsonResult.getMsg() : "操作失败，请重试";
                    return JsonResult.error(errMsg);
                }
            }else {
                JsonResult jsonResult = sysUserRpc.createOrUpdateTimeTemplates(device.getSerialNum(),
                        device.getProductCode(), record, jsonObject, exTimeArr,true);
                if(jsonResult != null && jsonResult.getSuccess()){
                    count = timeTempalteMapper.updateByKey(record);
                    saveOrUpdateTimeSection(record,jsonObject,exTimeArr,true);
                    msg = "更新成功";
                }else {
                    String errMsg = jsonResult != null ? jsonResult.getMsg() : "操作失败，请重试";
                    return JsonResult.error(errMsg);
                }
            }
            if(count > 0){
                return JsonResult.ok(msg,"");
            }else {
                return JsonResult.error("操作失败，请重试");
            }
        }else {
            return JsonResult.error("获取设备信息失败，请重试");
        }
    }

    private void saveOrUpdateTimeSection(CdzxkacsTimeTempalte record, JSONObject jsonObject, JSONArray exTimeArr,boolean isUpdate) {
        String templateId = record.getId();
        if(jsonObject != null && jsonObject.size() > 0){
            if(isUpdate){
                deleteAll(templateId);
            }
            CdzxkacsWeekPlan weekPlan = new CdzxkacsWeekPlan();
            weekPlan.setNum(jsonObject.size());
            weekPlan.setEnabled(1); //  默认1：使能
            weekPlan.setTemplateId(templateId);
            weekPlanMapper.insert(weekPlan);
            CdzxkacsDayPlan dayPlan1 = new CdzxkacsDayPlan();
            int dayNum = 0;
            for (String keyNum : jsonObject.keySet()) {
                int num = Integer.parseInt(keyNum);
                JSONArray jsonArray = jsonObject.getJSONArray(keyNum);
                CdzxkacsDayPlan dayPlan = new CdzxkacsDayPlan();
                dayPlan.setWeekIndex(num);
                dayPlan.setNum(jsonArray.size());
                dayPlan.setWeekPlanId(weekPlan.getId());
                dayPlanMapper.insert(dayPlan);
                dayPlan1.setId(dayPlan.getId());
                if(jsonArray.size() == 1){
                    int beginSlot = (Integer) jsonArray.get(0);
                    CdzxkacsTimeSection timeSection = new CdzxkacsTimeSection();
                    timeSection.setDayPlanId(dayPlan.getId());
                    timeSection.setArmingType(0); //默认定时类型
                    timeSection.setBegin(parseTimeSlot(beginSlot)+":00:00");
                    timeSection.setEnd(parseTimeSlot(beginSlot)+":59:59");
                    timeSectionMapper.insert(timeSection);
                }else {
                    List<Integer> timeSlotList = new ArrayList<>();
                    for (int i = 0; i < jsonArray.size(); i++) {
                        int timeSlot = (Integer) jsonArray.get(i);
                        timeSlotList.add(timeSlot);
                    }
                    // 排序,用户先点击后面的再点击前面的会出现这种情况
                    Collections.sort(timeSlotList);
                    //int b = 0,e; // 6 7 8 10
                    for (int i = 0; i < timeSlotList.size(); i++) {
                        int begin = timeSlotList.get(i);
                        int end = begin;
                        int step = 0;
                        if(timeSlotList.contains((begin+1))){
                            for (int j = i+1; j < timeSlotList.size(); j++) {
                                int b = timeSlotList.get(j);
                                if((b-end==1)){
                                    end = b;
                                    step++;
                                }else {
                                    break;
                                }
                            }
                        }
                        i = i + step;
                        CdzxkacsTimeSection timeSection = new CdzxkacsTimeSection();
                        timeSection.setDayPlanId(dayPlan.getId());
                        timeSection.setBegin(parseTimeSlot(begin)+":00:00");
                        timeSection.setEnd(parseTimeSlot(end)+":59:59");
                        timeSection.setArmingType(0); //默认定时类型
                        timeSectionMapper.insert(timeSection);
                        dayNum++;
                    }
                    dayPlan1.setNum(dayNum);
                    dayPlanMapper.updateByKey(dayPlan1);
                }
            }
        }
        if(exTimeArr != null && exTimeArr.size() > 0){
            if(isUpdate){
                exceptionMapper.deleteByTemplateId(templateId);
            }
            for (int i = 0; i < exTimeArr.size(); i++) {
                JSONObject obj = exTimeArr.getJSONObject(i);
                CdzxkacsException exceDate = new CdzxkacsException();
                exceDate.setTemplateId(templateId);
                exceDate.setExceptionDate(obj.getString("id"));
                exceptionMapper.insert(exceDate);
            }
        }
    }

    @Override
    public Map<String, Object> getTimeTemplate(String templateId) {
        Map<String, Object> resultMap = new HashMap<>();
        if(!StringUtils.isEmpty(templateId)){
            HashMap param = new HashMap();
            param.put("templateId",templateId);
            List<CdzxkacsException> exTimes = exceptionMapper.list(param);
            List<String> exTimeList = new ArrayList<>();
            for(CdzxkacsException ex : exTimes){
                exTimeList.add(ex.getExceptionDate());
            }
            resultMap.put("exTimeList",exTimeList);
            // {"1":[6,8,7],"3":[7],"4":[10],"6":[11]}
            HashMap param2 = new HashMap();
            param2.put("templateId",templateId);
            CdzxkacsWeekPlan weekPlan = weekPlanMapper.selectOne(param2);
            if(weekPlan != null){
                HashMap param3 = new HashMap();
                param3.put("weekPlanId",weekPlan.getId());
                JSONObject jsonObject = new JSONObject();
                List<CdzxkacsDayPlan> dayPlans = dayPlanMapper.list(param3);
                for(CdzxkacsDayPlan dayPlan : dayPlans){
                    HashMap param4 = new HashMap();
                    param4.put("dayPlanId",dayPlan.getId());
                    List<CdzxkacsTimeSection> timeSections = timeSectionMapper.list(param4);
                    List<Integer> list = new ArrayList<>();
                    for (int i = 0; i < timeSections.size(); i++) {
                        String beginStr = timeSections.get(i).getBegin();
                        String endStr = timeSections.get(i).getEnd();
                        if(!StringUtils.isEmpty(beginStr) && !StringUtils.isEmpty(endStr)){
                            int begin = Integer.parseInt(beginStr.substring(0,beginStr.indexOf(":")));
                            int end = Integer.parseInt(endStr.substring(0,endStr.indexOf(":")));
                            //[begin,end]区间 [0,2]
                            for (int j = begin; j <= end; j++) {
                                list.add(j);
                            }
                        }
                    }
                    jsonObject.put(String.valueOf(dayPlan.getWeekIndex()),list.toArray());
                }
                resultMap.put("bfTimes",jsonObject);
            }
        }
        return resultMap;
    }

}
